﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
//using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace BreakerControlSoft
{
    /*class ListViewNF : System.Windows.Forms.ListView
    {
        public ListViewNF()
        {
            // 开启双缓冲
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

            // Enable the OnNotifyMessage event so we get a chance to filter out 
            // Windows messages before they get to the form's WndProc
            this.SetStyle(ControlStyles.EnableNotifyMessage, true);
        }

        protected override void OnNotifyMessage(Message m)
        {
            //Filter out the WM_ERASEBKGND message
            if (m.Msg != 0x14)
            {
                base.OnNotifyMessage(m);
            }
        }
    }*/

    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void SetPortProperty()//设置串口的属性
        {
            GLOBAL.sp.PortName = cbxCOMPort.Text.Trim();//设置串口名
            GLOBAL.sp.BaudRate = int.Parse(cbxBaud.SelectedItem.ToString());
            GLOBAL.sp.DataBits = 8;
            //GLOBAL.sp.DataBits = 9;
            GLOBAL.sp.StopBits = StopBits.One;
            //GLOBAL.sp.Parity = Parity.None;
            //btnSetComm_Click(null, null);
            GLOBAL.sp.ReadTimeout = -1;//设置超时读取时间
            //GLOBAL.sp.RtsEnable = true; //定义DataReceived事件，当串口收到数据后触发事件 
            //GLOBAL.sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
        }

        private void btnCheckCOM_Click(object sender, EventArgs e)
        {
            bool comExistence = false;//有可用串口标志位 
            cbxCOMPort.Items.Clear();//清除当前串口号中的所有串口名称
            for (int i = 0; i < 20; i++)
            {
                try
                {
                    GLOBAL.sp = new SerialPort("COM" + (i + 1).ToString());
                    GLOBAL.sp.Open();
                    GLOBAL.sp.Close();
                    cbxCOMPort.Items.Add("COM" + (i + 1).ToString());
                    comExistence = true;
                }
                catch (Exception)
                {
                    continue;
                }
            }
            if (comExistence)
            {
                cbxCOMPort.SelectedIndex = 0;//使ListBox显示第1个添加的索引
            }
            else
            {
                MessageBox.Show("没有找到可用串口！", "错误提示");
            }
        }

        private void btnOpenCOM_Click(object sender, EventArgs e)
        {
            GLOBAL.sp.BaudRate = int.Parse(cbxBaud.SelectedItem.ToString());
            /*switch (cbxParity.SelectedItem.ToString())
            {
                case "n":
                    GLOBAL.sp.Parity = Parity.None;
                    break;
                case "e":
                    GLOBAL.sp.Parity = Parity.Even;
                    break;
                case "o":
                    GLOBAL.sp.Parity = Parity.Odd;
                    break;
            }*/
            if (!GLOBAL.isOpen)
            {
                if (cbxCOMPort.Text.Trim() == "")//检测串口设置
                {
                    MessageBox.Show("串口未设置！", "错误提示");
                    return;
                }
                if (!GLOBAL.isSetProperty)//串口未设置则设置串口
                {
                    SetPortProperty();
                    GLOBAL.isSetProperty = true;
                }
                try//打开串口
                {
                    GLOBAL.sp.Open();
                    GLOBAL.isOpen = true;
                    btnOpenCOM.Text = "关闭串口"; //串口打开后则相关的串口设置按钮便不可再用
                    btnCheckCOM.Enabled = false;
                    cbxCOMPort.Enabled = false;
                }
                catch (Exception)
                { //打开串口失败后，相应标志位取消
                    GLOBAL.isSetProperty = false;
                    GLOBAL.isOpen = false;
                    MessageBox.Show("串口无效或已被占用！", "错误提示");
                }
            }
            else
            {
                try//打开串口
                {
                    GLOBAL.sp.Close();
                    GLOBAL.isOpen = false;
                    GLOBAL.isSetProperty = false;
                    btnOpenCOM.Text = "打开串口"; //关闭串口后，串口设置选项便可以继续使用
                    btnCheckCOM.Enabled = true;
                    cbxCOMPort.Enabled = true;
                }
                catch (Exception)
                {
                    MessageBox.Show("关闭串口时发生错误", "错误提示");
                }
            }
        }

        private RadioButton[] radioCMD = new RadioButton[10];

        private void FrmShowData_Load(object sender, EventArgs e)
        {
            tabMain.Controls.Remove(PageCeShi);
            tabMain.Controls.Remove(PageTiaoShi);
            lblCTime.Visible = false; lblOTime.Visible = false; txtCTime.Visible = false; txtOTime.Visible = false; lblCTimeNote.Visible = false; lblOTimeNote.Visible = false;

            cbxBaud.Items.Add("2400");
            cbxBaud.Items.Add("4800");
            cbxBaud.Items.Add("9600");
            cbxBaud.Items.Add("19200");
            cbxBaud.Items.Add("57600");
            cbxBaud.Items.Add("115200");

            cbxParity.Items.Add("n");
            cbxParity.Items.Add("e");
            cbxParity.Items.Add("o");

            cbxBaud.SelectedItem = "9600";
            cbxParity.SelectedItem = "n";
            //cbxSensorAddr.SelectedItem = "2";
            listData.View = View.Details;
            ColumnHeader ch = new ColumnHeader();
            ch.Width = 100;
            ch.TextAlign = HorizontalAlignment.Left;
            listData.Columns.Add(ch);

            ch = new ColumnHeader();
            ch.Width = 500;
            ch.TextAlign = HorizontalAlignment.Left;
            listData.Columns.Add(ch);

            txtSensorID.Text = "50";
            btnSetID_Click(null,null);

            //ShowData(new byte[0], Color.Red, "执行成功：");

            GLOBAL.sp = new SerialPort();

            radioCMD[0] = radioCMD1; radioCMD[1] = radioCMD2; radioCMD[2] = radioCMD3; radioCMD[3] = radioCMD4;
            radioCMD[4] = radioCMD5; radioCMD[5] = radioCMD6; radioCMD[6] = radioCMD7; radioCMD[7] = radioCMD8;
            radioCMD[8] = radioCMD9; radioCMD[9] = radioCMD10;


        }

        private bool GetOpTime()
        {
            //设置C2OTime
            if(!GLOBAL.IsInteger(txtC2OTime.Text))
            {
                MessageBox.Show("关断-开启时间非法输入！");
                return false;
            }
            int tmptime = int.Parse(txtC2OTime.Text);
            if (GLOBAL.CurUser == GLOBAL.ADMIN && (tmptime < 20 || tmptime > 300))
            {
                MessageBox.Show("管理员账户：关断开启时间最小值为20ms，最大值为300ms，请检查！");
                return false;
            }
            if (GLOBAL.CurUser == GLOBAL.USER && (tmptime < 100 || tmptime > 300))
            {
                MessageBox.Show("普通账户：关断开启时间最小值为100ms，最大值为300ms，请检查！");
                return false;
            }
            GLOBAL.C2OTime = tmptime;
            //设置O2CTime
            if (!GLOBAL.IsInteger(txtO2CTime.Text))
            {
                MessageBox.Show("开启-关断时间非法输入！");
                return false;
            }
            tmptime = int.Parse(txtO2CTime.Text);
            if (GLOBAL.CurUser == GLOBAL.ADMIN && (tmptime < 10 || tmptime > 300))
            {
                MessageBox.Show("管理员账户：开启关断时间最小值为20ms，最大值为300ms，请检查！");
                return false;
            }
            if (GLOBAL.CurUser == GLOBAL.USER && (tmptime < 100 || tmptime > 300))
            {
                MessageBox.Show("普通账户：开启关断时间最小值为100ms，最大值为300ms，请检查！");
                return false;
            }
            GLOBAL.O2CTime = tmptime;
            //设置间隔时间
            if (!GLOBAL.IsInteger(txtIntvalTime.Text))
            {         
                MessageBox.Show("关断-开启时间非法输入！");
                return false;
            }
            tmptime = int.Parse(txtIntvalTime.Text);
            if (GLOBAL.CurUser == GLOBAL.ADMIN && (tmptime < 1 || tmptime > 180))
            {
                MessageBox.Show("管理员账户：间隔时间最小值为1s，最大值为180s，请检查！");
                return false;
            }
            if (GLOBAL.CurUser == GLOBAL.USER && (tmptime < 1 || tmptime > 180))
            {
                MessageBox.Show("普通账户：间隔时间最小值为1s，最大值为180s，请检查！");
                return false;
            }
            GLOBAL.IntvalTime = tmptime;
            return true;
        }

        private bool SetOpTime()
        {
            if (!GetOpTime())
                return false;
            if (!GLOBAL.isOpen)
            {
                MessageBox.Show("串口未打开！");
                return false;
            }
            byte[] timedata = new byte[6]{(byte)(GLOBAL.C2OTime >> 8),(byte)(GLOBAL.C2OTime&0x00FF),(byte)(GLOBAL.O2CTime >> 8),(byte)(GLOBAL.O2CTime&0x00FF),(byte)(GLOBAL.IntvalTime >> 8),(byte)(GLOBAL.IntvalTime & 0x00FF)};
            if (SendCMD70(0x33, 0x1100, timedata) != GLOBAL.CMD_SUCCESS)
                return false;
            return true;
        }

        //67号指令 读取寄存器
        private int SendCMD67(byte DevAddr, short RegAddr,int Recvlen, byte[] RegDataRecv)
        {
            byte[] BytesToSend = new Byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };   //固定16字节长度，不够最后补0
            BytesToSend[0] = DevAddr;     //数据头
            BytesToSend[1] = 0x42;
            BytesToSend[2] = (byte)(RegAddr >> 8);
            BytesToSend[3] = (byte)(RegAddr & 0x00FF);            //uint bytelen = (uint)(ByteSend.Length);
            BytesToSend[4] = (byte)(Recvlen >> 8);
            BytesToSend[5] = (byte)(Recvlen & 0x00FF);
            uint crc16 = GLOBAL.crc16_modbus(BytesToSend, 6);
            //BytesToSend[6] = (Byte)(crc16 & 0x00FF);
            //BytesToSend[7] = (Byte)((crc16 >> 8) & 0x00FF);
            try
            {
                ShowData(BytesToSend, Color.Black, "发送：");
                GLOBAL.sp.DiscardInBuffer();
                GLOBAL.sp.Write(BytesToSend, 0, BytesToSend.Length);
                Thread.Sleep(200);
                int tmpcnt = 0;
                Byte[] ReceivedData = new byte[0];
                while (GLOBAL.sp.BytesToRead < 16)
                {
                    Thread.Sleep(1);
                    tmpcnt++;
                    if (tmpcnt > 2000)    //超时
                    {
                        ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                        GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                        ShowData(ReceivedData, Color.Red, "接收超时！！");
                        return GLOBAL.CMD_TIMEOUT;
                    }
                }
                ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                crc16 = (uint)(((ReceivedData[4 + Recvlen] << 8) & 0xFF00) | (ReceivedData[3 + Recvlen] & 0x00FF));
                /*if (GLOBAL.crc16_modbus(ReceivedData, (uint)(3 + Recvlen)) != crc16)
                {
                    ShowData(ReceivedData, Color.Red, "CRC校验错误：");
                    return GLOBAL.CMD_CRC_ERROR;
                }*/
                if (BytesToSend[1] != ReceivedData[1])
                {
                    ShowData(ReceivedData, Color.Red, "写入失败：");
                    return GLOBAL.CMD_FAIL;
                }
                for (int i = 0; i < Recvlen; i++)
                {
                    RegDataRecv[i] = ReceivedData[i + 3];
                }
                ShowData(ReceivedData, Color.Red, "执行成功：");
            }
            catch (Exception e)
            {
                Thread.Sleep(400);
                return GLOBAL.CMD_EXCEPTION;
            }
            return GLOBAL.CMD_SUCCESS;
        }
        //70号指令对应发送接收程序
        private int SendCMD70(byte DevAddr,short RegAddr,byte[] ByteSend)
        {
            //int cmdlen = ByteSend.Length + 8;
            byte[] BytesToSend = new Byte[16]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   //固定16字节长度，不够最后补0
            BytesToSend[0] = DevAddr;     //数据头
            BytesToSend[1] = 0x45;
            BytesToSend[2] = (byte)(RegAddr >> 8);
            BytesToSend[3] = (byte)(RegAddr & 0x00FF);
            uint bytelen = (uint)(ByteSend.Length);
            BytesToSend[4] = (byte)(bytelen >> 8);
            BytesToSend[5] = (byte)(bytelen & 0x00FF);
            for (int i = 0; i < bytelen; i++)
            {
                BytesToSend[6 + i] = ByteSend[i];
            }
            uint crc16 = GLOBAL.crc16_modbus(BytesToSend, 6 + bytelen);
            BytesToSend[6+bytelen] = (Byte)(crc16 & 0x00FF);
            BytesToSend[7+bytelen] = (Byte)((crc16 >> 8) & 0x00FF);
            //BytesToSend[6 + bytelen] = 0;
            //BytesToSend[7 + bytelen] = 0;
            //Int16 iTemp;
            try
            {
                ShowData(BytesToSend, Color.Black, "发送：");
                GLOBAL.sp.DiscardInBuffer();
                //GLOBAL.sp.Parity = Parity.Even;
                //GLOBAL.sp.Write(BytesToSend, 0, BytesToSend.Length);
                GLOBAL.sp.Parity = Parity.Mark;
                GLOBAL.sp.Write(new byte[]{BytesToSend[0]}, 0, 1);
                //Thread.Sleep(2);
                //下面发送数据
                byte[] tmpbuffer = new byte[BytesToSend.Length - 1];
                for (int i = 0; i < BytesToSend.Length - 1; i++) tmpbuffer[i] = BytesToSend[i + 1];
                GLOBAL.sp.Parity = Parity.Space;
                GLOBAL.sp.Write(tmpbuffer, 0, BytesToSend.Length-1);
                //GLOBAL.sp.DiscardInBuffer();
                Thread.Sleep(100);
                int tmpcnt = 0;
                Byte[] ReceivedData = new byte[0];
                while (GLOBAL.sp.BytesToRead < 16)
                {
                    Thread.Sleep(1);
                    tmpcnt++;
                    if (tmpcnt > 2000)    //超时
                    {
                        ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                        GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                        ShowData(ReceivedData, Color.Red, "数据帧接收超时！！");
                        return GLOBAL.CMD_TIMEOUT;
                    }
                }
                ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                //crc16 = (uint)(((ReceivedData[8] << 8) & 0xFF00) | (ReceivedData[7] & 0x00FF));
                //if (GLOBAL.crc16_modbus(ReceivedData, 7) != crc16)
                //{
                //    ShowData(ReceivedData, Color.Red, "CRC校验错误：");
                //    return GLOBAL.CMD_CRC_ERROR;
                //}

                if (BytesToSend[1] != ReceivedData[1])
                {
                    ShowData(ReceivedData, Color.Red, "写入失败：");
                    return GLOBAL.CMD_FAIL;
                }
                ShowData(ReceivedData, Color.Red, "执行成功：");
            }
            catch (Exception e)
            {
                Thread.Sleep(400);
                return GLOBAL.CMD_EXCEPTION;
            }
            return GLOBAL.CMD_SUCCESS;
        }


        private void FrmShowData_FormClosing(object sender, FormClosingEventArgs e)
        {
            //bThreadRun = false;
            //while (!bThreadEnd) Thread.Sleep(10);
        }

        private void lblDataShow_Click(object sender, EventArgs e)
        {

        }

        private void cbxSensorAddr_SelectedValueChanged(object sender, EventArgs e)
        {
            
        }

        private void cbxSensorAddr_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        private void FrmShowData_Click(object sender, EventArgs e)
        {
            //lblShowTemp.Focus();
            
        }

        private void btnSetComm_Click(object sender, EventArgs e)
        {

        }

        private void btnSetID_Click(object sender, EventArgs e)
        {
            if (!GLOBAL.bIsInputTextNumlegal(txtSensorID.Text))
            {
                MessageBox.Show("非法输入！");
                return;
            }
            int addr = int.Parse(txtSensorID.Text);
            if (addr > 255)
            {
                MessageBox.Show("请输入0-255的整数！");
                return;
            }
            GLOBAL.Sensor_addr = addr;
            lblAddr.Text = "当前传感器编号：" + GLOBAL.Sensor_addr.ToString();
        }

        /*
        private int SendOCCMD(byte phaseID,byte CMD)
        {
            byte[] BytesToSend = new Byte[8];
            BytesToSend[0] = (Byte)(GLOBAL.Sensor_addr);     //数据头
            BytesToSend[1] = 69;
            BytesToSend[2] = 0x00;
            BytesToSend[3] = phaseID;
            BytesToSend[4] = CMD;
            BytesToSend[5] = 0x00;
            uint crc16 = GLOBAL.crc16_modbus(BytesToSend, 6);
            BytesToSend[6] = (Byte)(crc16 & 0x00FF);
            BytesToSend[7] = (Byte)((crc16 >> 8) & 0x00FF);
            //Int16 iTemp;
            try
            {
                ShowData(BytesToSend, Color.Black, "发送：");
                GLOBAL.sp.DiscardInBuffer();
                GLOBAL.sp.Write(BytesToSend, 0, 8);
                Thread.Sleep(200);
                int tmpcnt = 0;
                Byte[] ReceivedData = new byte[0];
                while (GLOBAL.sp.BytesToRead < 8)
                {
                    Thread.Sleep(1);
                    tmpcnt++;
                    if (tmpcnt > 200)    //超时
                    {
                        ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                        GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                        ShowData(ReceivedData, Color.Red, "接收超时！！");
                        return GLOBAL.CMD_TIMEOUT;
                    }
                }
                ReceivedData = new Byte[GLOBAL.sp.BytesToRead];//创建接收字节数组
                GLOBAL.sp.Read(ReceivedData, 0, GLOBAL.sp.BytesToRead);//读取所接收到的数据
                crc16 = (uint)(((ReceivedData[8] << 8) & 0xFF00) | (ReceivedData[7] & 0x00FF));
                if (GLOBAL.crc16_modbus(ReceivedData, 7) != crc16)
                {
                    ShowData(ReceivedData, Color.Red, "CRC校验错误：");
                    return GLOBAL.CMD_CRC_ERROR;
                }
                if (ReceivedData[4] != CMD)
                {
                    ShowData(ReceivedData, Color.Red, "命令执行失败：");
                    return GLOBAL.CMD_FAIL;
                }
                ShowData(ReceivedData, Color.Red, "执行成功：");
            }
            catch (Exception e)
            {
                Thread.Sleep(400);
                return GLOBAL.CMD_EXCEPTION;
            }
            return GLOBAL.CMD_SUCCESS;
        }*/

        void ShowData(byte[] buf,Color color,string quote)
        {
            listData.BeginUpdate();
            ListViewItem item = new ListViewItem();
            string strtmp = quote;
            for(int i = 0;i < buf.Length;i++)
            {
                strtmp += (buf[i].ToString("X2") + " ");
            }
            item.Text = DateTime.Now.ToString("HH:mm:ss");
            item.SubItems.Add(strtmp);
            item.ForeColor = color;
            listData.Items.Add(item);
            listData.Items[listData.Items.Count - 1].EnsureVisible();
            listData.EndUpdate();
        }

        private void btnOpenCMD_Click(object sender, EventArgs e)
        {
            ShowData(new byte[2]{0x55,0x66}, Color.Red, "执行成功：");
        }

        private void lblLoopCnt_Click(object sender, EventArgs e)
        {

        }

        private void btnAdminLog_Click(object sender, EventArgs e)
        {
            if (GLOBAL.CurUser == GLOBAL.USER)
            {
                FrmInput input = new FrmInput("密码输入");
                if (input.ShowDialog() == DialogResult.OK)
                {
                    if (input.strInput != "admin")
                    {
                        MessageBox.Show("密码错误！");
                        return;
                    }
                }
                else return;
                GLOBAL.CurUser = GLOBAL.ADMIN;
                MessageBox.Show("管理员账户登录成功！");
                btnAdminLog.Text = "管理员注销"; lblUser.Text = "当前账户：管理员"; lblUser.ForeColor = Color.Red;
                tabMain.Controls.Add(PageCeShi);tabMain.Controls.Add(PageTiaoShi);
                lblCTime.Visible = true; lblOTime.Visible = true; txtCTime.Visible = true; txtOTime.Visible = true; lblCTimeNote.Visible = true; lblOTimeNote.Visible = true;
            }
            else
            {
                GLOBAL.CurUser = GLOBAL.USER;
                MessageBox.Show("管理员账户注销成功！");
                btnAdminLog.Text = "管理员登录"; lblUser.Text = "当前账户：普通用户"; lblUser.ForeColor = Color.Black;
                tabMain.Controls.Remove(PageCeShi);tabMain.Controls.Remove(PageTiaoShi);
                lblCTime.Visible = false; lblOTime.Visible = false; txtCTime.Visible = false; txtOTime.Visible = false; lblCTimeNote.Visible = false; lblOTimeNote.Visible = false;
            }
        }

        private void btnSendTestCMD_Click(object sender, EventArgs e)
        {
            if (!SetOpTime()) return;
            int CMDindex = -1;
            for (int i = 0; i < 8; i++)
            {
                if (radioCMD[i].Checked)
                {
                    CMDindex = i;
                    break;
                }
            }
            if (CMDindex == -1)
            {
                MessageBox.Show("没有项被选中！");
                return;
            }
            if (SendCMD70(0x33, (short)(CMDindex + 1), new byte[]{}) != GLOBAL.CMD_SUCCESS)
            {
                MessageBox.Show("命令发送出现问题！");
                return;
            }
            MessageBox.Show("命令发送成功！");
        }

        private void btnLoopCMDSend_Click(object sender, EventArgs e)
        {
            if (!GLOBAL.isOpen)
            {
                MessageBox.Show("串口未打开！");
                return;
            }
            if (!SetOpTime()) return;
            if(!GLOBAL.IsInteger(txtLoopCnt.Text))
            {
                MessageBox.Show("循环次数非法输入！");
                return;
            }
            int tmpcnt = int.Parse(txtLoopCnt.Text);
            if (tmpcnt < 0 || tmpcnt > 30000)
            {
                MessageBox.Show("数值过大或过小！");
                return;
            }
            int checkindex = 0;
            for(int i=8;i<10;i++)
            {
                if(radioCMD[i].Checked)
                {
                    checkindex = i;
                }
            }
            byte[] bytedata = new byte[]{(byte)(tmpcnt >> 8),(byte)(tmpcnt & 0x00FF)};
            if (SendCMD70(0x33, (short)(checkindex+1), bytedata) != GLOBAL.CMD_SUCCESS)
            {
                MessageBox.Show("命令发送失败！");
                return;
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            listData.Items.Clear();
        }

        private void btnWriteTimeParam_Click(object sender, EventArgs e)
        {
            SetOpTime();
        }

        private void btnWriteOCParam_Click(object sender, EventArgs e)
        {
            if (!GLOBAL.isOpen)
            {
                MessageBox.Show("串口未打开！");
                return;
            }
            if (!GLOBAL.IsInteger(txtCPulseTime.Text))
            {
                MessageBox.Show("合闸脉冲时间非法输入！");
                return;
            }
            int tmpint = int.Parse(txtCPulseTime.Text);
            if (tmpint < 15 || tmpint > 100)
            {
                MessageBox.Show("合闸脉冲时间最小值为15ms，最大值为100ms！");
                return;
            }
            GLOBAL.CPulseTime = tmpint;
            //**************************************
            if (!GLOBAL.IsInteger(txtOPulseTime.Text))
            {
                MessageBox.Show("分闸脉冲时间非法输入！");
                return;
            }
            tmpint = int.Parse(txtOPulseTime.Text);
            if (tmpint < 0 || tmpint > 50)
            {
                MessageBox.Show("分闸脉冲时间最小值为0ms，最大值为50ms！");
                return;
            }
            GLOBAL.OPulseTime = tmpint;
            //*************************************
            if (!GLOBAL.IsFloatValid(txtCTime.Text,2,1))
            {
                MessageBox.Show("合闸时间非法输入！");
                return;
            }
            float tmpfloat = float.Parse(txtCTime.Text);
            if (tmpint < 0 || tmpint > 25)
            {
                MessageBox.Show("合闸时间最小值为0ms，最大值为25ms！");
                return;
            }
            GLOBAL.CTime = (int)(tmpfloat * 10);
            //************************************
            if (!GLOBAL.IsFloatValid(txtOTime.Text, 2, 1))
            {
                MessageBox.Show("分闸时间非法输入！");
                return;
            }
            tmpfloat = float.Parse(txtOTime.Text);
            if (tmpfloat < 0 || tmpfloat > 25)
            {
                MessageBox.Show("分闸时间最小值为0ms，最大值为25ms！");
                return;
            }
            GLOBAL.OTime = (int)(tmpfloat * 10);

            //开始发送指令
            byte[] bytedata;
            short RegAddr;
            if (GLOBAL.CurUser == GLOBAL.ADMIN)
            {
                bytedata = new byte[] { (byte)(GLOBAL.CPulseTime >> 8), (byte)(GLOBAL.CPulseTime & 0xff), (byte)(GLOBAL.OPulseTime >> 8), (byte)(GLOBAL.OPulseTime & 0xff), 
                (byte)(GLOBAL.CTime >> 8), (byte)(GLOBAL.CTime & 0xff),(byte)(GLOBAL.OTime >> 8), (byte)(GLOBAL.OTime & 0xff)};
                RegAddr = 0x0A00;
            }
            else
            {
                bytedata = new byte[] { (byte)(GLOBAL.CPulseTime >> 8), (byte)(GLOBAL.CPulseTime & 0xff), (byte)(GLOBAL.OPulseTime >> 8), (byte)(GLOBAL.OPulseTime & 0xff)};
                RegAddr = 0x0A01;
            }
            if (SendCMD70(0x55, RegAddr, bytedata) != GLOBAL.CMD_SUCCESS)
            {
                MessageBox.Show("写入失败！");
                return;
            }
        }

        private void btnReadOCParam_Click(object sender, EventArgs e)
        {
            if (!GLOBAL.isOpen)
            {
                MessageBox.Show("串口未打开！");
                return;
            }
            byte[] RegVal = new byte[8]{0,0,0,0,0,0,0,0};
            if (SendCMD67(0x55, 0x000A, 8,RegVal) != GLOBAL.CMD_SUCCESS)
            {
                MessageBox.Show("读取失败！");
                return;
            }
            txtCPulseTime.Text = ((RegVal[0] << 8) + RegVal[1]).ToString();
            txtOPulseTime.Text = ((RegVal[2] << 8) + RegVal[3]).ToString();
            txtCTime.Text = (((RegVal[4] << 8) + RegVal[5])/10.0).ToString();
            txtOTime.Text = (((RegVal[6] << 8) + RegVal[7])/10.0).ToString();

        }

        /*
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(100);//延时100ms等待接收完数据
            this.Invoke((EventHandler)(delegate
            {
                Byte Byte0 = (byte)GLOBAL.sp.ReadByte();
                Byte Byte1 = (byte)GLOBAL.sp.ReadByte();
                if (Byte0 == 0xAA && Byte1 == 0x55)     //校验起始位
                {
                    Byte[] ReceivedData = new Byte[25];//创建接收字节数组
                    GLOBAL.sp.Read(ReceivedData, 0, 25);//读取所接收到的数据
                }
                GLOBAL.sp.DiscardInBuffer();//丢弃接收缓冲区数据
            }));
        }*/

    }
}
